import { cloneDeep } from 'lodash-es'
import { Subject } from 'rxjs'
import { filter, takeUntil, takeWhile, tap } from 'rxjs/operators'

export interface EventOptions<D extends any[]> {
  handle: (...data: D) => void
  takeUntilFlag?: Subject<any>
  once?: boolean
}

export class AdEvent {
  private static readonly eventBus$: Subject<any> = new Subject()
  /**
   * 事件发送
   */
  public static $sent<T extends any[]>(event: string, ...data: T) {
    AdEvent.eventBus$.next([event, ...data])
  }
  /**
   * 事件监听
   */
  public static $on<D extends any[]>(
    event: string | string[],
    { handle = () => {}, takeUntilFlag = new Subject(), once = false }: EventOptions<D>
  ) {
    let takeWhileFlag = true
    return AdEvent.eventBus$
      .pipe(
        tap((_data) => {
          // console.log(`${data[0]}事件触发`, data);
        }),
        takeWhile((_v) => takeWhileFlag),
        takeUntil(takeUntilFlag),
        filter((res) => {
          if (typeof event === 'string') {
            return res[0] === event
          } else {
            return event.includes(res[0])
          }
        }),
        tap((_data) => {
          if (once) {
            takeWhileFlag = false
          }
          // console.log(`${data[0]}事件触发`, data);
        })
      )
      .subscribe((data) => {
        const cloneData: D = cloneDeep(data)
        cloneData.shift()
        handle(...cloneData)
      })
  }
}
